﻿/* ----------------------------------------------------------------------------
 * Copyright (c) Rob Ashton 2009
 *
 * This source code is subject to terms and conditions of the Microsoft Public 
 * License (Ms-PL).
 * 
 * By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 * 
 * To request a copy of the Microsoft Public License, send a request by email
 * to license@mvcex.com
 *
 * This notice must not be removed from this software.
 * ---------------------------------------------------------------------------- */


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Moq;
using System.Web;
using MvcEx.Configuration;
using MvcEx.Theming;

namespace MvcEx.Tests
{
    [TestFixture]
    public class MvcExThemePathResolverTests
    {
        [Test]
        public void locate_file_that_exists_in_current_theme()
        {
            var contextMock = new Mock<HttpContextBase>();
            var serverMock = new Mock<HttpServerUtilityBase>();
            var requestMock = new Mock<HttpRequestBase>();
            serverMock.Setup(x => x.MapPath(It.IsAny<String>())).Returns((String path) => TestHelper.MapPath("MvcExPathResolverTests", path));
            requestMock.SetupGet(x => x.ApplicationPath).Returns("/");
            contextMock.SetupGet(x => x.Server).Returns(serverMock.Object);
            contextMock.SetupGet(x => x.Request).Returns(requestMock.Object);

            String providedMaster = "/themes/standard/somepath/inside/directory/exists.master";

            String masterLocation = MvcExThemePathResolver.ResolveThemeFileLocation(
                "sometheme",
                MvcExConstants.THEME_DIRECTORY,
                contextMock.Object,
                providedMaster);

            Assert.NotNull(masterLocation);
            Assert.True(masterLocation.Contains("sometheme"));
        }

        [Test]
        public void locate_file_that_does_not_exist_in_current_theme()
        {
            var contextMock = new Mock<HttpContextBase>();
            var serverMock = new Mock<HttpServerUtilityBase>();
            var requestMock = new Mock<HttpRequestBase>();
            serverMock.Setup(x => x.MapPath(It.IsAny<String>())).Returns((String path) => TestHelper.MapPath("MvcExPathResolverTests", path));
            requestMock.SetupGet(x => x.ApplicationPath).Returns("/");
            contextMock.SetupGet(x => x.Server).Returns(serverMock.Object);
            contextMock.SetupGet(x => x.Request).Returns(requestMock.Object);

            String providedMaster = "/themes/standard/somepath/inside/directory/exists.master";

            String masterLocation = MvcExThemePathResolver.ResolveThemeFileLocation(
                "invalidtheme",
                MvcExConstants.THEME_DIRECTORY,
                contextMock.Object,
                providedMaster);

            Assert.NotNull(masterLocation);
            Assert.True(masterLocation.Contains("standard"));
        }

        [Test]
        public void locate_file_that_does_not_exist_in_current_theme_excludes_virtual_directory() {
            var contextMock = new Mock<HttpContextBase>();
            var serverMock = new Mock<HttpServerUtilityBase>();
            var requestMock = new Mock<HttpRequestBase>();
            serverMock.Setup(x => x.MapPath(It.IsAny<String>())).Returns((String path) => TestHelper.MapPath("MvcExPathResolverTests", path));
            requestMock.SetupGet(x => x.ApplicationPath).Returns("/MyVirtual");
            contextMock.SetupGet(x => x.Server).Returns(serverMock.Object);
            contextMock.SetupGet(x => x.Request).Returns(requestMock.Object);

            String providedMaster = "/MyVirtual/themes/standard/somepath/inside/directory/exists.master";

            String masterLocation = MvcExThemePathResolver.ResolveThemeFileLocation(
                "invalidtheme",
                MvcExConstants.THEME_DIRECTORY,
                contextMock.Object,
                providedMaster);

            Assert.NotNull(masterLocation);
            Assert.AreEqual("/themes/standard/somepath/inside/directory/exists.master", masterLocation);
        }

        [Test]
        public void locate_root_relative_file_that_does_not_exist_in_current_theme_excludes_virtual_directory() {
            var contextMock = new Mock<HttpContextBase>();
            var serverMock = new Mock<HttpServerUtilityBase>();
            var requestMock = new Mock<HttpRequestBase>();
            serverMock.Setup(x => x.MapPath(It.IsAny<String>())).Returns((String path) => TestHelper.MapPath("MvcExPathResolverTests", path));
            requestMock.SetupGet(x => x.ApplicationPath).Returns("/MyVirtual");
            contextMock.SetupGet(x => x.Server).Returns(serverMock.Object);
            contextMock.SetupGet(x => x.Request).Returns(requestMock.Object);

            String providedMaster = "~/themes/standard/somepath/inside/directory/exists.master";

            String masterLocation = MvcExThemePathResolver.ResolveThemeFileLocation(
                "invalidtheme",
                MvcExConstants.THEME_DIRECTORY,
                contextMock.Object,
                providedMaster);

            Assert.NotNull(masterLocation);
            Assert.AreEqual("/themes/standard/somepath/inside/directory/exists.master", masterLocation);
        }

        [Test]
        public void locate_file_when_original_not_in_themes_directory()
        {
            var contextMock = new Mock<HttpContextBase>();
            var serverMock = new Mock<HttpServerUtilityBase>();
            serverMock.Setup(x => x.MapPath(It.IsAny<String>())).Returns((String path) => TestHelper.MapPath("MvcExPathResolverTests", path));
            contextMock.SetupGet(x => x.Server).Returns(serverMock.Object);

            String providedMaster = "somefile.master";


            String masterLocation = MvcExThemePathResolver.ResolveThemeFileLocation(
                "invalidtheme",
                MvcExConstants.THEME_DIRECTORY,
                contextMock.Object,
                providedMaster);

            Assert.NotNull(masterLocation);
            Assert.AreEqual(providedMaster, masterLocation);
        }

        [Test]
        public void locate_file_when_original_in_wrong_themes_directory()
        {
            var contextMock = new Mock<HttpContextBase>();
            var serverMock = new Mock<HttpServerUtilityBase>();
            var requestMock = new Mock<HttpRequestBase>();
            serverMock.Setup(x => x.MapPath(It.IsAny<String>())).Returns((String path) => TestHelper.MapPath("MvcExPathResolverTests", path));
            requestMock.SetupGet(x => x.ApplicationPath).Returns("/");
            contextMock.SetupGet(x => x.Server).Returns(serverMock.Object);
            contextMock.SetupGet(x => x.Request).Returns(requestMock.Object);

            String providedMaster = "/somewhere/stupid/themes/somefile.master";

            String masterLocation = MvcExThemePathResolver.ResolveThemeFileLocation(
                "invalidtheme",
                MvcExConstants.THEME_DIRECTORY,
                contextMock.Object,
                providedMaster);

            Assert.NotNull(masterLocation);
            Assert.AreEqual(providedMaster, masterLocation);
        }

        [Test]
        public void tidy_path_which_has_trailing_slashes()
        {
            var contextMock = new Mock<HttpContextBase>();
            var requestMock = new Mock<HttpRequestBase>();
            requestMock.SetupGet(x => x.ApplicationPath).Returns("/");
            contextMock.SetupGet(x => x.Request).Returns(requestMock.Object);

            String output = MvcExThemePathResolver.TidyLinkedResourcePath(contextMock.Object, "\\//somewhere\\site.css");

            Assert.AreEqual("/somewhere/site.css", output);
        }

        [Test]
        public void tidy_path_which_has_wrongfacing_slashes()
        {
            var contextMock = new Mock<HttpContextBase>();
            var requestMock = new Mock<HttpRequestBase>();
            requestMock.SetupGet(x => x.ApplicationPath).Returns("/");
            contextMock.SetupGet(x => x.Request).Returns(requestMock.Object);

            String output = MvcExThemePathResolver.TidyLinkedResourcePath(contextMock.Object, "\\somewhere\\site.css");

            Assert.AreEqual("/somewhere/site.css", output);
        }

        [Test]
        public void tidy_path_with_no_virtual_directory()
        {
            var contextMock = new Mock<HttpContextBase>();
            var requestMock = new Mock<HttpRequestBase>();
            requestMock.SetupGet(x => x.ApplicationPath).Returns("/");
            contextMock.SetupGet(x => x.Request).Returns(requestMock.Object);

            String output = MvcExThemePathResolver.TidyLinkedResourcePath(contextMock.Object, "site.css");

            Assert.AreEqual("/site.css", output);
        }

        [Test]
        public void tidy_path_with_virtual_directory()
        {
            var contextMock = new Mock<HttpContextBase>();
            var requestMock = new Mock<HttpRequestBase>();
            requestMock.SetupGet(x => x.ApplicationPath).Returns("/virtualdir");
            contextMock.SetupGet(x => x.Request).Returns(requestMock.Object);

            String output = MvcExThemePathResolver.TidyLinkedResourcePath(contextMock.Object, "site.css");

            Assert.AreEqual("/virtualdir/site.css", output);
        }
    }
}
